python人脸识别和人脸对比,face

您所在的位置:网站首页 黑暗中的人脸 图片大全 python人脸识别和人脸对比,face

python人脸识别和人脸对比,face

2024-07-09 18:35| 来源: 网络整理| 查看: 265

前言 先用OpenCV判断图片是否模糊,模糊的话需要重拍;再用face_recognition检测图片中是否有人脸,有才接着进行下一步;再用face_recognition计算图片中每张人脸的128维人脸编码;最后用face_recognition将本次计算得到的人脸编码与以前已计算的进行对比,得到一个相似度最高的结果。上一步中提到已计算的人脸编码,可以将它们存入向量数据库,如Milvus、Proxima等,这样对比的时候直接从数据库中查询就行。我用的Milvus,官网有它的增删改查文档,SDK我用的PyMilvus,注意安装PyMilvus时要选和你的Milvus的版本对应的版本,不能装错,这点在文档和GitHub中都有说。Milvus有个GUI的管理程序,Attu,在Milvus文档中也有介绍,它可以在网页上查看数据库中的数据。只用OpenCV也可以做人脸识别,我没试,参考链接里有。

写这篇文章之前,我从来没接触过这方面,查了一些基础知识,都在参考链接里,感谢他们的分享。

安装 linux

就安装dlib库和windows不一样,其他步骤一样,我只测试了CentOS 7.9.2009,服务器中有miniconda。

conda install -c conda-forge dlib,安装dlib库。

记录安装dlib库失败解决过程,认识conda-forge_后知前觉的博客-CSDN博客_dlib库安装失败

linux安装dlib,以下步骤解决所有问题。_weixin_41899102的博客-CSDN博客_linux安装dlib失败

linux系统下安装dlib_Batman。的博客-CSDN博客_linux安装dlib

windows

相比linux,windows的安装有点复杂

pip install cmakepip install boost从pypi或github或其他地方下载dlib库的whl文件,版本要和你的python版本一致,具体怎么选版本看我的上篇文章,并使用pip install安装pip install face_recognitionpip install opencv-python 使用

需要自己准备一些含有人脸的图片放入一个文件夹中,最好是人脸正面;再准备一张人脸图片放在和文件夹同级的目录中,这张图片中的人要和文件夹中某张图片是同一个人。

如有两张周杰伦的图片,一张放在文件夹中,另一张放在和文件夹同级的目录中,然后文件夹中再放一些不是周杰伦的图片。

拿着文件夹外的这张人脸图片,去和文件夹中的所有人脸图片对比,看有没有匹配到同一个人。具体的匹配原理,在代码注释和文章末尾的参考链接中。

本地测试 import face_recognition import os import time from numpy import array # 若不加这一行,对从文件中读取已保存的128维人脸编码执行eval()时,报错name 'array' is not defined import cv2 t1 = time.time() # 路径中不能有中文 source_img_file_path = r"C:\Users\PC-1\Desktop\ZhouJieLun1.png" img_folder_path = r"C:\Users\PC-1\Desktop\face_img" # 获取列表的第二个元素 def takeSecond(elem): return elem[1] # 判断图片是否清晰,参数是图片的绝对路径 def getImageVar(imgPath: str) -> bool: image = cv2.imread(imgPath) img2gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) imageVar = cv2.Laplacian(img2gray, cv2.CV_64F).var() # 一般大于100时认为图片是清晰的,实际需根据情况调节 if imageVar 100: return True # 检测图片中是否有人脸。能接受不完整的人脸,如缺少鼻子以下,此时是能否检测到人脸的阈值之一,人脸中其他部位的缺少情况未测试 def check_face_img(img_path: str) -> bool: img = face_recognition.load_image_file(img_path) # 加载图像。会将图像加载到 numpy 数组中。 result = face_recognition.face_locations(img) # 返回图像中每张人脸的人脸特征位置列表。图像中没有人脸时,返回空列表 if len(result)>0: return True else: return False # 获取图片库中每张图片的128维人脸编码,用于传给face_recognition.face_distance()的face_encodings参数 def get_face_encodings(img_folder_path): img_face_encoding_list = [] # 每个元素是文件夹中所有图片的128维人脸编码 img_path_list = [] # 每个元素是文件夹中图片的绝对路径 img_list = os.listdir(img_folder_path) for img in img_list: img_path = os.path.join(img_folder_path, img) if getImageVar(img_path) and check_face_img(img_path): img_path_list.append(img_path) img = face_recognition.load_image_file(img_path) # 加载图像 img_face_encoding = face_recognition.face_encodings(img)[0] # 返回图像中每张人脸的 128 维人脸编码。后面使用face_recognition.face_distance()时,face_recognition.face_distance()的face_encodings参数中的值不能是由face_recognition.face_encodings(img)组成的,而应由face_recognition.face_encodings(img)[0]组成。 img_face_encoding_list.append(img_face_encoding) elif not getImageVar(img_path): print(f'{img_path}图片太模糊,请重新拍摄,入库时已忽略此图片') elif not check_face_img(img_path): print(f'{img_path}没有检测到完整人脸,请重新拍摄,入库时已忽略此图片') return img_face_encoding_list, img_path_list img_face_encoding_list, img_path_list = get_face_encodings(img_folder_path) # 从本地文件读取已保存的图片库中每张图片的128维人脸编码,节省计算时间 def get_face_encodings_from_file(): with open(r"C:\Users\PC-1\Desktop\img_face_encoding_list.txt", 'r', encoding='utf-8') as f: img_face_encoding_list = eval(f.read()) # 需from numpy import array,否则eval()报错name 'array' is not defined img_path_list=[] img_list = os.listdir(img_folder_path) for img in img_list: img_path = os.path.join(img_folder_path, img) img_path_list.append(img_path) return img_face_encoding_list, img_path_list # img_face_encoding_list, img_path_list = get_face_encodings_from_file() if getImageVar(source_img_file_path) and check_face_img(source_img_file_path): img = face_recognition.load_image_file(source_img_file_path) # face_locations = face_recognition.face_locations(img) # 返回图像中每张人脸的人脸特征位置列表。face_locations为(顶部、右侧、底部、左侧)顺序找到的人脸位置的元组列表 source_img_face_encoding = face_recognition.face_encodings(img)[0] result = face_recognition.face_distance(face_encodings=img_face_encoding_list, face_to_compare=source_img_face_encoding) # 给定人脸编码列表,将它们与已知的人脸编码进行比较,并得到每个比较人脸的欧氏距离。距离大小为面孔的相似程度。欧氏距离越小相似度越大。欧氏距离的典型阈值是0.6,即小于0.6的可认为匹配成功。face_encodings是要比较的人脸编码列表,face_to_compare是要与之进行比较的人脸编码。 temp_list = list(zip(img_path_list, result)) temp_list.sort(key=takeSecond) # 将原列表按列表中每个子元素中的第二个元素的值进行升序排列 print(temp_list) if temp_list[0][-1] < 0.6: # 升序排列后第一个元素的相似度最高,如果它的欧氏距离小于0.6,认为匹配成功 print(temp_list[0]) else: print('匹配失败') # 有可能不是本人,也有可能是本次拍摄时不清晰 elif not getImageVar(source_img_file_path): print('图片太模糊,请重新拍摄') elif not check_face_img(source_img_file_path): print('没有检测到完整人脸,请重新拍摄') t2 = time.time() print(t2-t1) # 每次运行都计算所有图片的特征值,与6张图片对比耗时4.7秒;直接从本地文件读取已保存的图片库中每张图片的128维人脸编码,与6张图片对比耗时0.6秒。

img_face_encoding_list.txt的内容的示例

[array([-0.01729634, 0.10430054, 0.07625537, 0.03276102, -0.07866749, -0.02818274, -0.06889073, -0.04842021, 0.13796961, -0.05026057, 0.23302871, 0.00723806, -0.2370982 , -0.01487464, -0.06505933, 0.10084826, -0.1636425 , -0.07501083, -0.12756079, -0.10016631, 0.04007092, 0.0581928 , 0.03240498, -0.01134465, -0.13176998, -0.2787565 , -0.07050405, -0.09639949, 0.09951212, -0.14790948, 0.03040591, 0.0431371 , -0.15323421, 0.01086914, 0.0220076 , 0.01904444, -0.00923841, -0.06280316, 0.18326622, 0.03018811, -0.14447245, -0.01474072, -0.01069712, 0.24571334, 0.24511024, 0.02628675, -0.04335158, -0.0862942 , 0.06775976, -0.25436637, 0.011755 , 0.20667061, 0.05011301, 0.13582194, 0.05677999, -0.16563055, 0.02566983, 0.11052104, -0.15707225, -0.00112594, 0.02829274, -0.05549442, -0.03616317, -0.05381152, 0.13676476, 0.04478186, -0.09165385, -0.12494379, 0.12897444, -0.18318115, -0.00553679, 0.09620941, -0.12292095, -0.19553109, -0.20274746, 0.08238635, 0.38079879, 0.18709588, -0.14765534, 0.01780803, -0.05188759, -0.02483106, 0.03612664, -0.0149317 , -0.10475352, -0.05023222, -0.05713973, 0.07221895, 0.14290087, -0.05685572, 0.01866397, 0.22389664, -0.04868836, 0.01686323, 0.02283146, -0.01206459, -0.05818488, 0.05559994, -0.09816868, 0.00713632, 0.06758018, -0.11922558, 0.04631898, 0.06196419, -0.13793124, 0.0963118 , 0.01178237, -0.03925588, 0.04579747, 0.01644197, -0.13718042, -0.04710923, 0.24413618, -0.24439959, 0.27725762, 0.2127548 , 0.04380967, 0.12280341, 0.07158501, 0.13633233, -0.03227835, -0.03378378, -0.09766266, -0.03692475, 0.01623037, -0.04219364, -0.03954222, -0.04019544]), array([-3.03432867e-02, 5.43443598e-02, 6.78744391e-02, 2.58869212e-02, -1.23072207e-01, -7.02521503e-02, -4.98226285e-02, -1.72496010e-02, 7.67212510e-02, -4.26685344e-03, 1.95951223e-01, -1.67683400e-02, -2.15903431e-01, -4.35754284e-03, -3.12260389e-02, 7.05019981e-02, -1.18235752e-01, -8.07965323e-02, -1.49761930e-01, -1.44610867e-01, 3.96064669e-02, 4.81094792e-02, 8.37654807e-03, -3.67331831e-03, -1.19957335e-01, -2.90346920e-01, -8.59770030e-02, -1.07959040e-01, 1.21038556e-01, -1.51315838e-01, 3.27938870e-02, 4.70837858e-03, -1.73844323e-01, -3.17394398e-02, 2.35435199e-02, 1.66472271e-02, -1.98804624e-02, -9.39380080e-02, 1.69165611e-01, 6.68221340e-03, -1.77107140e-01, 1.08059309e-02, 2.33938862e-02, 2.76533812e-01, 2.21089691e-01, 2.53173988e-02, -1.82928685e-02, -5.52510098e-02, 6.09008260e-02, -2.64982283e-01, 3.63944210e-02, 1.93908125e-01, 1.00877725e-01, 1.14827916e-01, 7.65965059e-02, -1.46504432e-01, 3.48312259e-02, 1.25334620e-01, -1.56430572e-01, 2.46226899e-02, 2.86777914e-02, -3.82297374e-02, -1.68778505e-02, -1.19121701e-01, 1.69600606e-01, 4.99524400e-02, -8.64719599e-02, -1.21018678e-01, 1.09727934e-01, -1.94434166e-01, -3.34550738e-02, 8.30303952e-02, -1.11592978e-01, -1.87120140e-01, -2.38885000e-01, 1.09276593e-01, 3.92007828e-01, 2.01715931e-01, -1.94086283e-01, 2.30474807e-02, -8.15587863e-02, -1.26086362e-02, 2.73021199e-02, -1.08986711e-02, -1.09373406e-01, -5.31885028e-03, -8.07625800e-02, 6.63535371e-02, 1.74903929e-01, -9.10659656e-02, 3.04515511e-02, 1.86322704e-01, -2.50804201e-02, 9.74564068e-03, 2.13033091e-02, -3.06630391e-04, -1.11615628e-01, 3.51248235e-02, -9.08284336e-02, 1.10836141e-03, 1.00318097e-01, -1.36240765e-01, 5.00137471e-02, 8.65165964e-02, -1.79704651e-01, 1.37958780e-01, 5.58579108e-04, -7.75038823e-02, 1.49468854e-02, 1.46387927e-02, -8.91202837e-02, -3.77928428e-02, 2.32269630e-01, -2.34496534e-01, 2.73653299e-01, 2.40941241e-01, 3.94841023e-02, 1.35746434e-01, 5.84627874e-02, 1.05018303e-01, -5.28650098e-02, -1.84285827e-02, -1.11144938e-01, -4.56666909e-02, 1.28744273e-02, -4.79294769e-02, -4.71757315e-02, -6.85334997e-03]), array([-1.19727597e-01, 2.37059481e-02, 5.41203022e-02, -5.31067979e-03, -1.02095716e-01, -6.70940429e-02, 5.28478026e-02, -9.28077772e-02, 1.14727125e-01, -5.81904836e-02, 1.65611401e-01, -9.44045261e-02, -2.55105197e-01, -4.14437950e-02, -2.89703198e-02, 1.06697828e-01, -9.61818695e-02, -1.10643283e-01, -1.84341758e-01, -9.77335051e-02, 8.45019799e-03, 6.26069605e-02, -1.26636475e-02, 5.73121430e-03, -1.16348065e-01, -2.58341700e-01, -7.38507137e-02, -1.35549113e-01, 6.04273453e-02, -6.86645284e-02, 3.62175442e-02, 1.11231357e-01, -1.17278963e-01, -5.90739734e-02, 2.98288725e-02, 3.80353555e-02, 8.69030412e-03, -8.14783499e-02, 2.00276792e-01, -3.30614746e-02, -1.73424274e-01, -8.51858705e-02, 8.01797211e-02, 1.89619228e-01, 1.80681810e-01, -3.04257311e-02, 8.26369599e-03, -1.84000656e-02, 3.17999758e-02, -2.45052502e-01, -3.82037610e-02, 1.40862808e-01, 1.22625537e-01, 9.89214256e-02, 5.23140244e-02, -1.46283448e-01, -8.13427381e-03, 1.29438370e-01, -1.73568085e-01, 7.16047511e-02, 1.99302640e-02, -1.64908677e-01, -6.60278201e-02, -2.77188811e-02, 1.60548747e-01, 8.64261240e-02, -8.74619484e-02, -1.47788346e-01, 1.73828602e-01, -1.89269871e-01, -4.95751537e-02, 8.37096721e-02, -1.09814622e-01, -1.14491023e-01, -2.01664209e-01, 2.60536000e-03, 3.81230652e-01, 1.08411252e-01, -1.66443884e-01, -6.42048474e-03, -1.52495116e-01, -6.41984940e-02, -2.20064986e-02, 8.72708671e-03, -3.22415009e-02, -1.00544520e-01, -9.76137221e-02, -1.15213916e-04, 2.00150207e-01, -7.71829262e-02, 1.90558862e-02, 1.59315109e-01, -2.54158806e-02, -5.27779348e-02, -2.89773215e-02, -4.60110046e-03, -1.19977474e-01, -8.91544484e-03, -2.61534844e-03, -5.38323261e-02, 9.46650878e-02, -1.22638777e-01, 4.54899520e-02, 9.24251229e-02, -1.47666842e-01, 1.31898567e-01, -3.10513265e-02, -2.91747078e-02, 3.84223610e-02, -3.18786129e-02, -2.67100539e-02, -5.41412318e-03, 2.24448472e-01, -1.44214451e-01, 2.11022705e-01, 1.61338180e-01, -4.03464250e-02, 1.21684045e-01, 2.53224019e-02, 1.12374000e-01, -1.62403062e-02, 1.75351724e-02, -1.21122740e-01, -1.05977543e-01, 1.91601515e-02, -2.42309403e-02, -3.90784908e-03, 9.26381629e-03])] 将人脸编码存入Milvus 文档中的示例代码

先放出文档中的基本使用的代码,我是按照文档中的提示一步一步复制的,这里我只测试了插入和查询,每一页末尾都有下一步的提示(截图中的中文是浏览器翻译的),代码使用时需将host改成你自己的服务器ip。

代码注释中的中文文档链接现在已经跳转到英文文档了,因为我反馈了中文文档有问题,后来官方就删了中文文档,或者虽然没删但不让你访问中文文档了。

from pymilvus import connections, CollectionSchema, FieldSchema, DataType, Collection import random # 代码是从2.0.0中文文档复制的 # 从gitee的README中https://gitee.com/milvus-io/milvus#%E5%90%AF%E5%8A%A8-milvus中'安装 Milvus 单机版'进入中文文档https://milvus.io/cn/docs/v2.0.0/install_standalone-docker.md # 从github的README中https://github.com/milvus-io/milvus#install-milvus中'Standalone Quick Start Guide'进入英文文档https://milvus.io/docs/v2.0.x/install_standalone-docker.md # 中文文档可能有字母大小写错误(会导致报错),最好看英文文档 connections.connect(alias="default", host='YOUR HOST', port='19530') # 构建一个 Milvus 连接,alias是创建的Milvus连接的别名 # 准备架构,包括字段架构、集合架构和集合名称。 book_id = FieldSchema( name="book_id", dtype=DataType.INT64, is_primary=True, ) word_count = FieldSchema( name="word_count", dtype=DataType.INT64, ) book_intro = FieldSchema( name="book_intro", dtype=DataType.FLOAT_VECTOR, # 一个集合中必须有一个字段是DataType.FLOAT_VECTOR或DataType.BINARY_VECTOR类型,文档原话The collection to create must contain a primary key field and a vector field. INT64 is the only supported data type for the primary key field in current release of Milvus. from https://milvus.io/cn/docs/v2.0.0/create_collection.md#Prepare-Schema dim=2 # 向量列数,一个向量有多少个元素就有多少列。 ) schema = CollectionSchema( fields=[book_id, word_count, book_intro], description="Test book search" ) collection_name = "book" # 使用架构创建集合 collection = Collection( name=collection_name, schema=schema, using='default', # 服务器别名,要在哪个服务器创建集合 shards_num=2, consistency_level="Strong" ) # 准备要插入的数据。要插入的数据的数据类型必须与集合的架构匹配,否则 Milvus 将引发异常。 data = [ [i for i in range(2000)], [i for i in range(10000, 12000)], [[random.random() for _ in range(2)] for _ in range(2000)], ] collection = Collection("book") # Get an existing collection. mr = collection.insert(data) # 插入数据 # 为向量构建索引。矢量索引是元数据的组织单位,用于加速矢量相似性搜索。如果没有在向量上构建索引,Milvus将默认执行暴力搜索。 index_params = { # 准备索引参数 "metric_type":"L2", "index_type":"IVF_FLAT", "params":{"nlist":1024} } # 通过指定矢量字段名称和索引参数来构建索引 collection = Collection("book") # Get an existing collection. collection.create_index( field_name="book_intro", index_params=index_params ) # Milvus 中的所有搜索和查询操作都在内存中执行。在执行向量相似性搜索之前将 collection 加载到内存中。 collection = Collection("book") # Get an existing collection. collection.load() search_params = {"metric_type": "L2", "params": {"nprobe": 10}} # 准备适合你的搜索场景的参数。下面的示例定义了搜索将使用欧式距离计算,并从 IVF_FLAT 索引构建的十个最近的聚类中检索向量。 results = collection.search( # 进行向量搜索 data=[[0.1, 0.2]], anns_field="book_intro", param=search_params, limit=10, # 输出相似度最高的向量结果的数量 expr=None, consistency_level="Strong" # 从gitee的README进入的中文文档(https://milvus.io/cn/docs/v2.0.0/search.md#%E8%BF%9B%E8%A1%8C%E5%90%91%E9%87%8F%E6%90%9C%E7%B4%A2)中这里错写成strong,会有下面两行的报错,源码中说这个参数的介绍在https://github.com/milvus-io/milvus/blob/master/docs/developer_guides/how-guarantee-ts-works.md,看了参数介绍中'if no consistency level was specified, search will use the consistency level when you create the collection.',再看Collection()创建集合时的代码(https://milvus.io/cn/docs/v2.0.0/create_collection.md#Create-a-collection-with-the-schema),发现是大小写错了。从github的README进入的英文文档没错。 # raise InvalidConsistencyLevel(0, f"invalid consistency level: {consistency_level}") from e # pymilvus.client.exceptions.InvalidConsistencyLevel: ) # 查看最相似向量的 primary key 及其距离值 print(results[0].ids) print(results[0].distances) collection.release() # 搜索完成时释放 Milvus 中加载的 collection 以减少内存消耗 connections.disconnect("default") # 断开 Milvus 连接 我的实际代码

使用时需将host改成你自己的服务器ip

import face_recognition import os import time import random from pymilvus import connections, CollectionSchema, FieldSchema, DataType, Collection import cv2 # 路径中不能有中文 img_folder_path = r"C:\Users\PC-1\Desktop\face_img" # 判断图片是否清晰,参数是图片的绝对路径 def getImageVar(imgPath: str) -> bool: image = cv2.imread(imgPath) img2gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) imageVar = cv2.Laplacian(img2gray, cv2.CV_64F).var() # 一般大于100时认为图片是清晰的,实际需根据情况调节 if imageVar 100: return True # 检测图片中是否有人脸。能接受不完整的人脸,如缺少鼻子以下,此时是能否检测到人脸的阈值之一,人脸中其他部位的缺少情况未测试 def check_face_img(img_path: str) -> bool: img = face_recognition.load_image_file(img_path) # 加载图像。会将图像加载到 numpy 数组中。 result = face_recognition.face_locations(img) # 返回图像中每张人脸的人脸特征位置列表。图像中没有人脸时,返回空列表 if len(result)>0: return True else: return False connections.connect(alias="default", host='YOUR HOST', port='19530') # 构建一个 Milvus 连接,alias是创建的Milvus连接的别名 # 准备架构,包括字段架构、集合架构和集合名称。 face_id = FieldSchema( name="face_id", dtype=DataType.INT64, is_primary=True, auto_id=False # 关闭自动赋值自增id,实际人员的id由前端传入 ) face_feature_vector = FieldSchema( name="face_feature_vector", dtype=DataType.FLOAT_VECTOR, # 128维人脸编码是浮点数。一个集合中必须有一个字段是DataType.FLOAT_VECTOR或DataType.BINARY_VECTOR类型,文档原话The collection to create must contain a primary key field and a vector field. INT64 is the only supported data type for the primary key field in current release of Milvus. from https://milvus.io/cn/docs/v2.0.0/create_collection.md#Prepare-Schema dim=128 # face_recognition.face_encodings()返回的列表再取第一个元素,值是128维人脸编码。向量列数,一个向量有多少个元素就有多少列。 ) schema = CollectionSchema( fields=[face_id, face_feature_vector], description="face feature vector test test test" ) collection_name = "face_feature_vector_test_test" # 使用架构创建集合 collection = Collection( name=collection_name, schema=schema, using='default', # 服务器别名,要在哪个服务器创建集合 shards_num=2, consistency_level="Strong" ) # 准备要插入的数据。要插入的数据的数据类型必须与集合的架构匹配,否则 Milvus 将引发异常。 img_list = os.listdir(img_folder_path) for img in img_list: img_path = os.path.join(img_folder_path, img) if getImageVar(img_path) and check_face_img(img_path): img = face_recognition.load_image_file(img_path) # 加载图像 img_face_encoding = face_recognition.face_encodings(img)[0] # 返回图像中每张人脸的 128 维人脸编码。后面使用face_recognition.face_distance()时,face_recognition.face_distance()的face_encodings参数中的值不能是由face_recognition.face_encodings(img)组成的,而应由face_recognition.face_encodings(img)[0]组成。 temp_id = random.randint(0, 100000) # face_id字段的值,能唯一确定一个人,暂时随机产生,实际应由前端传入 collection = Collection("face_feature_vector_test_test") # Get an existing collection. mr = collection.insert([ [temp_id], [img_face_encoding] ]) # 插入数据。from https://github.com/milvus-io/milvus/discussions/10713 # print(mr) # 插入操作的执行结果 elif not getImageVar(img_path): print(f'{img_path}图片太模糊,请重新拍摄,入库时已忽略此图片') elif not check_face_img(img_path): print(f'{img_path}没有检测到完整人脸,请重新拍摄,入库时已忽略此图片') # 为向量构建索引。矢量索引是元数据的组织单位,用于加速矢量相似性搜索。如果没有在向量上构建索引,Milvus将默认执行暴力搜索。 index_params = { # 准备索引参数 "metric_type":"L2", "index_type":"IVF_FLAT", "params":{"nlist":1024} } # 通过指定矢量字段名称和索引参数来构建索引 collection = Collection("face_feature_vector_test_test") # Get an existing collection. collection.create_index( field_name="face_feature_vector", index_params=index_params ) # Milvus 中的所有搜索和查询操作都在内存中执行。在执行向量相似性搜索之前将 collection 加载到内存中。 collection = Collection("face_feature_vector_test_test") # Get an existing collection. collection.load() connections.disconnect("default") # 断开 Milvus 连接 从Milvus中查询

相似度有个阈值,返回符合阈值的所有结果。我这里的阈值0.2、0.6均来自参考链接中的文章。使用时需将host改成你自己的服务器ip

import face_recognition import os import time import random from pymilvus import connections, CollectionSchema, FieldSchema, DataType, Collection import cv2 t1 = time.time() # 路径中不能有中文 # source_img_file_path = r"C:\Users\PC-1\Desktop\ZhouJieLun1.png" source_img_file_path = r"C:\Users\PC-1\Desktop\LinJunJie2.png" # 判断图片是否清晰,参数是图片的绝对路径 def getImageVar(imgPath: str) -> bool: image = cv2.imread(imgPath) img2gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) imageVar = cv2.Laplacian(img2gray, cv2.CV_64F).var() # 一般大于100时认为图片是清晰的,实际需根据情况调节 if imageVar 100: return True # 检测图片中是否有人脸。能接受不完整的人脸,如缺少鼻子以下,此时是能否检测到人脸的阈值之一,人脸中其他部位的缺少情况未测试 def check_face_img(img_path: str) -> bool: img = face_recognition.load_image_file(img_path) # 加载图像。会将图像加载到 numpy 数组中。 result = face_recognition.face_locations(img) # 返回图像中每张人脸的人脸特征位置列表。图像中没有人脸时,返回空列表 if len(result)>0: return True else: return False if getImageVar(source_img_file_path) and check_face_img(source_img_file_path): connections.connect(alias="default", host='YOUR HOST', port='19530') # 构建一个 Milvus 连接,alias是创建的Milvus连接的别名 # Milvus 中的所有搜索和查询操作都在内存中执行。在执行向量相似性搜索之前将 collection 加载到内存中。 collection = Collection("face_feature_vector_test_test") # Get an existing collection. collection.load() search_params = {"metric_type": "L2", "params": {"nprobe": 10}} # 准备适合你的搜索场景的参数。下面的示例定义了搜索将使用欧式距离计算,并从 IVF_FLAT 索引构建的十个最近的聚类中检索向量。 img = face_recognition.load_image_file(source_img_file_path) # 加载图像 img_face_encoding = face_recognition.face_encodings(img)[0] results = collection.search( # 进行向量搜索 data=[img_face_encoding], anns_field="face_feature_vector", param=search_params, limit=2, # 输出相似度最高的向量结果的数量,即输出几个与被匹配人脸最相似的人脸特征向量 expr=None, consistency_level="Strong" # 从gitee的README进入的中文文档(https://milvus.io/cn/docs/v2.0.0/search.md#%E8%BF%9B%E8%A1%8C%E5%90%91%E9%87%8F%E6%90%9C%E7%B4%A2)中这里错写成strong,会有下面两行的报错,源码中说这个参数的介绍在https://github.com/milvus-io/milvus/blob/master/docs/developer_guides/how-guarantee-ts-works.md,看了参数介绍中'if no consistency level was specified, search will use the consistency level when you create the collection.',再看Collection()创建集合时的代码(https://milvus.io/cn/docs/v2.0.0/create_collection.md#Create-a-collection-with-the-schema),发现是大小写错了。从github的README进入的英文文档没错。 # raise InvalidConsistencyLevel(0, f"invalid consistency level: {consistency_level}") from e # pymilvus.client.exceptions.InvalidConsistencyLevel: ) # 查看最相似向量的 primary key 及其距离值 id_list = results[0].ids distance_list = results[0].distances # print(id_list) # print(distance_list) if (len(list(id_list)) > 0) and (list(distance_list)[0]


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3